package com.cfweb.util;

import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;

import javax.ws.rs.core.MediaType;

import org.apache.http.HttpEntity;
import org.apache.http.HttpHeaders;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;
import org.springframework.http.HttpStatus;

import com.cfweb.exception.CloudFoundryApiException;

public class ResourceCall implements Callable<Map<String, Object>>{
	
	/**
	 * if you want to send http request
	 */
	final public static String HTTP = "http";
	
	/**
	 * if you want to remove some keys,
	 * attention : need to initial <b>keys</b>
	 */
	final public static String REMOVE = "remove";
	
	/**
	 * if you want to get just one value of the <b>key</b>
	 * attention : need to initial <b>keys</b> as its cascade
	 * 
	 */
	final public static String GETITEM= "get_one_item";
	private HttpClient httpClient;
	private HttpGet httpGet;
	private String type;
	private String[] keys;
	private Map<String, Object> resource;
	private String host;
	private String token;
	
	/**
	 * 
	 * @param hclient
	 * @param hget
	 * @param type
	 * @param session 
	 */
	public ResourceCall(HttpClient hclient, HttpGet hget, String type,String host,String token) {
		httpClient = hclient;
		httpGet = hget;
		this.type = type;
		this.host=host;
		this.token=token;
	}
	
	public ResourceCall(String type, Map<String, Object> resource, String[] keys) {
		this.type = type;
		this.resource = resource;
		this.keys = keys;
	}

	@Override
	public Map<String, Object> call() throws Exception {
		
		switch(type) {
			case HTTP : {
				return getResource();	
			}
			case REMOVE : {
				return removeResource();
			}
			case GETITEM : {
				return getOneItem();
			}
			default : {
				return null;
			}
		}
		
	}

	private Map<String, Object> getResource() throws Exception{
		HttpResponse response = httpClient.execute(httpGet);
		String resource = EntityUtils.toString(response.getEntity(), "UTF-8");
		Map<String, Object> mapRes = JsonUtil.convertJsonToMap(resource);
		if (!HttpStatusUtil.isSuccessStatus(response.getStatusLine().getStatusCode())){
			throw new CloudFoundryApiException(response.getStatusLine().getStatusCode(),(String)mapRes.get("description"));
		}
		if(mapRes.containsKey("resources")) {
			Map<String, Object> resourceMap = new HashMap<String, Object>();
			List<Map<String, Object>> lr = (List<Map<String, Object>>)mapRes.get("resources");
			String next_url=(String) mapRes.get("next_url");
			while(next_url!=null){
				next_url=retriveAllPageResource(lr,next_url,host,token);
			}
			resourceMap.put("list",lr);
			resourceMap.put("resource_size", mapRes.get("total_results"));
			return resourceMap;
		}
		return mapRes;			
	}
	
	private static String retriveAllPageResource(List<Map<String, Object>> lr,
			String next_url, String host,String token) throws Exception {
		HttpClient httpClient=null;
		HttpGet httpGet=null;
		String next_return_url=null;
		try{
			httpClient =  new DefaultHttpClient();
			httpGet = new HttpGet(host+next_url);
			httpGet.addHeader(HttpHeaders.HOST,host.substring(7));
			httpGet.addHeader(HttpHeaders.AUTHORIZATION, token);
			httpGet.addHeader(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON);
			httpGet.addHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON);
			HttpResponse response = httpClient.execute(httpGet);
			HttpEntity resentity = response.getEntity();  
			String content = EntityUtils.toString(resentity, "UTF-8"); 
			Map<String, Object> data = JsonUtil.convertJsonToMap(content);
			if (!HttpStatusUtil.isSuccessStatus(response.getStatusLine().getStatusCode())){
				throw new CloudFoundryApiException((Integer)data.get("code"),(String)data.get("description"));
			}
			lr.addAll((List<Map<String, Object>>)data.get("resources"));
			next_return_url=(String) data.get("next_url");
		}catch(Exception e){
			throw e;
		}
		return next_return_url;
	}
	
	private Map<String, Object> removeResource() {
		// TODO Auto-generated method stub
		return null;
	}
	
	@SuppressWarnings("unchecked")
	private Map<String, Object> getOneItem() throws ClientProtocolException, IOException {
		HttpResponse response = httpClient.execute(httpGet);
		String resource = EntityUtils.toString(response.getEntity(), "UTF-8");
		Map<String, Object> data = JsonUtil.convertJsonToMap(resource);
		if (!HttpStatusUtil.isSuccessStatus(response.getStatusLine().getStatusCode())){
			throw new CloudFoundryApiException(response.getStatusLine().getStatusCode(),(String)data.get("description"));
		}
		return data;
	} 


}
